﻿namespace Blip.API.Utility
{
    using System.Collections.Generic;
    using System.Text.RegularExpressions;

    /// <summary>
    /// Metody rozszerzające typ string.
    /// </summary>
    internal static class StringExtensions
    {
        #region Base64 Encode/Decode

        /// <summary>
        /// Koduje łańcuch to formatu Base64.
        /// </summary>
        /// <param name="str">Kodowany łańcuch</param>
        /// <returns>Sformatowany łańcuch</returns>
        public static string ToBase64(this string str)
        {
            byte[] buff = System.Text.Encoding.UTF8.GetBytes(str);
            return System.Convert.ToBase64String(buff);
        }

        /// <summary>
        /// Dekoduje łańcuch z formatu Base64.
        /// </summary>
        /// <param name="str">Zakodowany łańcuch</param>
        /// <returns>Odczytany łańcuch</returns>
        public static string FromBase64(this string str)
        {
            byte[] buff = System.Convert.FromBase64String(str);
            return System.Text.Encoding.UTF8.GetString(buff);
        }

        #endregion

        #region Add/Strip Slashes

        /// <summary>
        /// Dodaje znaki ucieczki do łańcucha.
        /// </summary>
        /// <param name="str">Obiekt string</param>
        /// <returns>Łańcuch uzupełniony o znaki ucieczki</returns>
        public static string AddSlashes(this string str)
        {
            var regex = new Regex(@"([\000\010\011\012\015\032\042\047\134\140])", RegexOptions.IgnoreCase);
            return regex.Replace(str, @"\$1");
        }

        /// <summary>
        /// Usuwa znaki ucieczki z łańcucha.
        /// </summary>
        /// <param name="str">Obiekt string</param>
        /// <returns>Łańcuch pozbawiony znaków ucieczki</returns>
        public static string StripSlashes(this string str)
        {
            var regex = new Regex(@"\\([\000\010\011\012\015\032\042\047\134\140])", RegexOptions.IgnoreCase);
            return regex.Replace(str, @"$1");
        }

        #endregion

        #region URL Encode/Decode

        private static IDictionary<string, string> replace = new Dictionary<string, string>();

        static StringExtensions()
        {
            var chars = "%$&+,/:;=?@ \"<>#{}|\\^~[]`".ToCharArray();
            foreach (var i in chars)
                replace.Add(i.ToString(), "%" + ((int)i).ToString("x"));
        }

        /// <summary>
        /// Koduje łańcuch do formatu zgodnego z URL.
        /// </summary>
        /// <param name="url">Kodowany tekst</param>
        /// <returns>Sformatowany tekst</returns>
        public static string EncodeUrl(this string url)
        {
            foreach (var i in replace)
                url = url.Replace(i.Key, i.Value);
            return url;
        }

        /// <summary>
        /// Dekoduje łańcuch z formatu URL.
        /// </summary>
        /// <param name="url">Zakodowany łańcuch</param>
        /// <returns>Zdekodowany łańcuch</returns>
        public static string DecodeUrl(this string url)
        {
            foreach (var i in replace)
                url = url.Replace(i.Value, i.Key);
            return url;
        }

        #endregion
    }
}